package com.lzx.applib.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.AbsoluteLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016/11/3.
 */

public class SortTextViews extends AbsoluteLayout {

    private static final String TAG = "SortTextViews";

    private int numColumn = 2;
    private List<String> data;

    private int vHeight, vWidth, vMargin;
    private View selectView;
    private View[] views;

    public SortTextViews(Context context) {
        this(context, null);
    }

    public SortTextViews(Context context, AttributeSet attrs) {
        super(context, attrs);

        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                getViewTreeObserver().removeGlobalOnLayoutListener(this);
                init();
            }
        });
    }

    public void setData(List<String> data) {
        this.data = data;
    }

    public void setNumColumn(int numColumn) {
        this.numColumn = numColumn;
    }

    private void init() {
        removeAllViews();
        views = new View[data.size()];
        int width = getWidth();

        for (int i=0; i<data.size(); i++) {
            String text = data.get(i);
            TextView tv = new TextView(getContext());
            tv.setText(text);
            tv.setTextSize(20);
            tv.setGravity(Gravity.CENTER);
            tv.setLayoutParams(getParamater(i));
            addView(tv);
            tv.setOnTouchListener(touchListener);
            views[i] = tv;
        }
    }

    OnTouchListener touchListener = new OnTouchListener() {
        int lastPosition = -1;
        int lastX, lastY;
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int x = (int) (v.getX() + event.getX());
            int y = (int) (v.getY() + event.getY());

            int dx = x - lastX;
            int dy = y - lastY;

            int curPosition = getPosition(x, y);

            int action = event.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    if (selectView != null) return false;
                    selectView = v;
                    break;
                case MotionEvent.ACTION_MOVE:
                    v.setX(v.getX() + dx);
                    v.setY(v.getY() + dy);
                    if (lastPosition != curPosition) {
                        Log.d(TAG, "onTouch()::" + lastPosition +" -> " + curPosition);
                        startAnim(lastPosition, curPosition);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    moveToPosition(selectView, lastPosition);
                    selectView = null;
                    break;
            }
            lastPosition = curPosition;
            lastX = x;
            lastY = y;
            return true;
        }
    };

    private LayoutParams getParamater(int position) {
        vWidth = getWidth()/numColumn;
        vHeight = 100;

        int x = position%numColumn * vWidth;
        int y = position/numColumn * vHeight;

        LayoutParams lp = new LayoutParams(vWidth, vHeight, x, y);
        return lp;
    }

    public int getPosition(int x, int y) {
        int position = y/vHeight * numColumn + x/vWidth;
        return Math.min(position, data.size()-1);
    }

    public void startAnim(int lastPosition, int curPosition) {
        if (lastPosition > curPosition) {
            for (int i = lastPosition-1; i>=curPosition; i--) {
                View view = views[i];
                moveToPosition(view, i+1);
                views[i+1] = view;
            }
            views[curPosition] = selectView;
        } else {
            for (int i = lastPosition+1; i<=curPosition; i++) {
                View view = views[i];
                moveToPosition(view, i-1);
                views[i-1] = view;
            }
            views[curPosition] = selectView;
        }
    }

    private void moveToPosition(final View v, int position) {
        AnimatorSet set = new AnimatorSet();
        set.setDuration(1000);
        LayoutParams lp = getParamater(position);
        ObjectAnimator animatorX = ObjectAnimator.ofFloat(v, "x", v.getX(), lp.x);
        ObjectAnimator animatorY = ObjectAnimator.ofFloat(v, "y", v.getY(), lp.y);
        set.play(animatorX).with(animatorY);
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                v.setOnTouchListener(null);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                v.setOnTouchListener(touchListener);
            }
        });
        set.start();
    }

    public List<String> getSortData() {
        List<String> data = new ArrayList<>();
        for (View view : views) {
            data.add(((TextView)view).getText().toString());
        }
        return data;
    }
}
